home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / sozobon2.zoo / ld / p1.c < prev    next >
C/C++ Source or Header  |  1990-12-13  |  7KB  |  429 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "ld.h"
  14.  
  15. extern int vflag, multipass, bflag;
  16.  
  17. char *myalloc();
  18. struct sinfo *lookup();
  19.  
  20. int ifd;
  21.  
  22. pass0(s)
  23. char *s;
  24. {
  25.     register struct finfo *fp;
  26.  
  27.     if (nfiles >= MAXFI) {
  28.         fprintf(stderr, "Too many files\n");
  29.         exit(1);
  30.     }
  31.     fp = &files[nfiles++];
  32.     fp->fname = s;    
  33.  
  34.     fp->fd = OPENBR(s);
  35.     if (fp->fd < 0) {
  36.         fprintf(stderr, "Cant open %s\n", s);
  37.         exit(1);
  38.     }
  39. }
  40.     
  41. fpass1(fname)
  42. char *fname;
  43. {
  44.     char buf[81], *s, *savestr();
  45.     FILE *ffd;
  46.  
  47.     ffd = fopen(fname, "r");
  48.     if (ffd == NULL) {
  49.         fprintf(stderr, "Cant open %s\n", fname);
  50.         exit(1);
  51.     }
  52.     while (fscanf(ffd, "%80s", buf) == 1) {
  53.         s = savestr(buf);
  54.         pass0(s);
  55.     }
  56. }
  57.  
  58. pass1(fn)
  59. {
  60.     register struct finfo *fp;
  61.     int i, n, nlost;
  62.  
  63.     fp = &files[fn];
  64.     if (vflag)
  65.         printf("%s:\n", fp->fname);
  66.  
  67.     ifd = fp->fd;
  68.  
  69.     read(ifd, &i, sizeof(int));
  70.     if (i == OMAGIC)
  71.         doobj(fn);
  72.     else if (i == AMAGIC)
  73.         doarch(fn);
  74.     else {
  75.         fprintf(stderr,"File '%s' not a valid object file or library\n",
  76.             fp->fname);
  77.         exit(1);
  78.     }
  79. }
  80.  
  81. doarch(fn)
  82. {
  83.     struct arch a;
  84.     int i;
  85.     long astart, ostart, tell();
  86.  
  87.     nskip = 0;
  88. more:
  89.     i = read(ifd, &a, sizeof(a));
  90.     if (i != sizeof(a) || a.anm[0] == 0)
  91.         goto out;
  92.  
  93.     ostart = tell(ifd);
  94.     astart = ostart + a.asize;
  95.  
  96.     doaobj(ostart, fn, a.anm);
  97.  
  98.     lseek(ifd, astart, 0);
  99.     goto more;
  100.  
  101. out:
  102.  
  103.     if (multipass)
  104.         m_redo(fn);
  105. }
  106.  
  107. doobj(fn)
  108. {
  109.     int i;
  110.  
  111.     i = read(ifd, (char *)&h + 2, sizeof(h)-2);
  112.  
  113.     if (i != sizeof(h)-2) {
  114.         fprintf(stderr, "File '%s' not a valid object file\n",
  115.             files[fn].fname);
  116.         return;
  117.     }
  118.  
  119.     doreally(&h, fn, NULL, NULL);
  120. }
  121.  
  122. doreally(hp, fn, aname, sptr)
  123. struct hdr *hp;
  124. char *aname, *sptr;
  125. {
  126.     register struct oinfo *p;
  127.     char *iptr;
  128.     long n, tell();
  129.  
  130.     if (nobj >= MAXOBJ) {
  131.         fprintf(stderr, "Obj table overflow\n");
  132.         exit(1);
  133.     }
  134.  
  135.     p = &obj[nobj];
  136.     p->fno = fn;
  137.     if (aname) {
  138.         strncpy(p->aname, aname, 14);
  139.         if (vflag)
  140.             printf("(%.14s)\n", aname);
  141.     }
  142.  
  143.     p->oh = *hp;
  144.     p->tbase = textsize;
  145.     p->dbase = datasize;
  146.     p->bbase = bsssize;
  147.  
  148.     n = hp->tsize+hp->dsize;
  149.     if (bflag) {
  150.         p->im_td = tell(ifd);
  151.         lseek(ifd, n, 1);
  152.     } else {
  153.         p->im_td = (long)myalloc(n);
  154.         lread(ifd, p->im_td, n);
  155.     }
  156.  
  157.     if (sptr) {
  158.         lseek(ifd, hp->syms, 1);
  159.     } else {
  160.         sptr = myalloc(hp->syms);
  161.         lread(ifd, sptr, hp->syms);
  162.     }
  163.     p->im_sym = sptr;
  164.  
  165.     if (bflag) {
  166.         p->im_rel = tell(ifd);
  167.     } else {
  168.         p->im_rel = (long)myalloc(n);
  169.         lread(ifd, p->im_rel, n);
  170.     }
  171.  
  172.     textsize += hp->tsize;
  173.     datasize += hp->dsize;
  174.     bsssize += hp->bsize;
  175.  
  176.     symabs(sptr);
  177.     n = hp->syms/sizeof(struct sym);
  178.     while (n--)
  179.         p1sym();
  180.  
  181.     nobj++;
  182.     return 1;
  183. }
  184.  
  185. doaobj(offs, fn, aname)
  186. long offs;
  187. char *aname;
  188. {
  189.     long n;
  190.     int i;
  191.     char *iptr;
  192.  
  193.     lseek(ifd, offs, 0);
  194.     i = read(ifd, &h, sizeof(h));
  195.  
  196.     if (i != sizeof(h) || h.magic != OMAGIC) {
  197.         fprintf(stderr,
  198.             "Member '%s' of library '%s' not a valid object file\n",
  199.             aname, files[fn].fname);
  200.         return;
  201.     }
  202.  
  203.     n = h.syms;
  204.     lseek(ifd, h.tsize+h.dsize, 1);
  205.     iptr = myalloc(n);
  206.     lread(ifd, iptr, n);
  207.  
  208.     symabs(iptr);
  209.  
  210.     if (norefs(h.syms)) {
  211.         if (multipass)
  212.             m_save(iptr, aname, offs);
  213.         else
  214.             free(iptr);
  215.         return;
  216.     } else {
  217.         lseek(ifd, offs + sizeof(h), 0);
  218.     }
  219.  
  220.     doreally(&h, fn, aname, iptr);
  221. }
  222.  
  223. m_save(iptr, aname, offs)
  224. char *iptr;
  225. char *aname;
  226. long offs;
  227. {
  228.     register struct skipstr *p;
  229.  
  230.     if (nskip >= MAXLIB) {
  231.         fprintf(stderr, "Skip table overflow\n");
  232.         exit(1);
  233.     }
  234.     p = &skip[nskip];
  235.     strncpy(p->aname, aname, 14);
  236.     p->oh = h;
  237.     p->ims = iptr;
  238.     p->offs = offs;
  239.     nskip++;
  240. }
  241.  
  242. m_redo(fn)
  243. {
  244.     register struct skipstr *p;
  245.     int rescan, i;
  246.  
  247.     if (vflag)
  248.         printf("Re-scan %s:\n", files[fn].fname);
  249.  
  250.     /* if need skipped objs
  251.         doreally()
  252.         p->ims = NULL
  253.         rescan++
  254.     */
  255. again:
  256.     rescan = 0;
  257.     p = skip;
  258.     for (i=0; i<nskip; i++,p++) {
  259.         if (p->ims == 0)
  260.             continue;
  261.  
  262.         symabs(p->ims);
  263.         if (norefs(p->oh.syms) == 0) {
  264.  
  265.             lseek(ifd, p->offs + sizeof(h), 0);
  266.  
  267.             doreally(&p->oh, fn, p->aname, p->ims);
  268.             p->ims = 0;
  269.             rescan++;
  270.         }
  271.     }
  272.  
  273.     if (rescan)
  274.         goto again;
  275. frees:
  276.     p = skip;
  277.     while (nskip--) {
  278.         if (p->ims)
  279.             free(p->ims);
  280.         p++;
  281.     }
  282. }
  283.  
  284. norefs(sy)
  285. long sy;
  286. {
  287.     long n, ftell();
  288.  
  289.     n = sy/sizeof(struct sym);
  290.     while (n--)
  291.         if (p1need())
  292.             return 0;
  293.     return 1;
  294. }
  295.  
  296. p1sym()
  297. {
  298.     struct sym s;
  299.     int i;
  300.  
  301.     i = symread(&s);
  302.     if (i != 1)
  303.         return;
  304.     if (not_glob(s.flags))
  305.         return;
  306.  
  307.     addsym(&s);
  308. }
  309.  
  310. addsym(s)
  311. struct sym *s;
  312. {
  313.     register struct sinfo *sp;
  314.  
  315.     if (oldsym(s))
  316.         return;
  317.  
  318.     if (nsym >= MAXSYM) {
  319.         fprintf(stderr, "Sym table overflow\n");
  320.         exit(1);
  321.     }
  322.  
  323.     sp = &sym[nsym];
  324.     sp->onum = nobj;
  325.     sp->sy = *s;
  326.     hashins(sp);
  327.     nsym++;
  328. }
  329.  
  330. struct sym zsym;
  331.  
  332. undef(name)
  333. char *name;
  334. {
  335.     struct sym s;
  336.     int sv;
  337.  
  338.     sv = nobj;
  339.     nobj = -1;
  340.  
  341.     s = zsym;
  342.     strncpy(s.name, name, 8);
  343.     s.flags = 0x88;
  344.     s.value = 0;
  345.     addsym(&s);
  346.  
  347.     nobj = sv;
  348. }
  349.  
  350. p1need()
  351. {
  352.     struct sym s;
  353.     int i;
  354.  
  355.     i = symread(&s);
  356.     if (i != 1)
  357.         return 0;
  358.     if (not_glob(s.flags))
  359.         return 0;
  360.     if (needsym(&s))
  361.         return 1;
  362.  
  363.     return 0;
  364. }
  365.  
  366. needsym(sp)
  367. struct sym *sp;
  368. {
  369.     struct sinfo *ip;
  370.     int ofl, nfl;
  371.  
  372.     nfl = sp->flags & 0xff;
  373.     if (nfl == 0x88 || nfl == 0xa8)
  374.         return 0;
  375.  
  376.     ip = lookup(sp->name);
  377.     if (ip == NULL)
  378.         return 0;
  379.     ofl = ip->sy.flags & 0xff;
  380.  
  381.     if (ofl == 0x88) {
  382.         if (vflag > 1)
  383.         printf("Needed %.8s\n", sp->name);
  384.         return 1;
  385.     }
  386.     return 0;
  387. }
  388.  
  389. oldsym(sp)
  390. struct sym *sp;
  391. {
  392.     struct sinfo *ip;
  393.     int ofl, nfl;
  394.  
  395.     ip = lookup(sp->name);
  396.     if (ip == NULL)
  397.         return 0;
  398.     ofl = ip->sy.flags & 0xff;
  399.     nfl = sp->flags & 0xff;
  400.     if (ofl == 0x88) {
  401.         ip->sy = *sp;
  402.         ip->onum = nobj;
  403.     } else if (nfl == 0x88) {
  404.         ;
  405.     } else if (ofl == 0xa8 && nfl == 0xa8) {
  406.         if (ip->sy.value != sp->value) {
  407.             fprintf(stderr, "Common sizes differ %.8s %ld %ld\n",
  408.                 ip->sy.name,
  409.                 ip->sy.value, sp->value);
  410.             if (sp->value > ip->sy.value)
  411.                 ip->sy.value = sp->value;
  412.         }
  413.     } else 
  414.         fprintf(stderr, "Double def of %.8s %x %x\n", sp->name,
  415.                 ofl, nfl);
  416.     return 1;
  417. }
  418.  
  419. not_glob(x)
  420. {
  421.     x &= 0xff;
  422.     if (x & 0x20)
  423.         return 0;
  424.  
  425.     if (x == 0x88)
  426.         return 0;
  427.     return 1;
  428. }
  429.